﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Resources;
using KnowledgeKiosk.FeedUpdaters;
using KnowledgeKiosk.Objects;
using KnowledgeKiosk.Parsers;
using Hardcodet.Scheduling;
using System.Windows.Input;

namespace KnowledgeKiosk
{
    public partial class MainPage : UserControl
    {
        private readonly Settings _settings;
        private Scheduler _scheduler;

        public string Theme { get; set; }

        public MainPage()
        {
            // Required to initialize variables
            InitializeComponent();

            _settings = (Settings)Application.Current.Resources["Settings"];

            this.KeyUp += delegate(Object s, KeyEventArgs args)
            {
                if (args.Key == Key.T)
                    RotateTheme();
            };

            InitializeCourseUpdater();
            InitializeBlogUpdater();
            InitializeWeatherUpdater();

            InitializeTheme();

            Logger.WriteLine("Initialized Knowledge Center Information Screen");
        }

        private void InitializeCourseUpdater()
        {
            var courseUpdater =
                new SharePointListItemsFeedUpdater<IEnumerable<Course>>(_settings.SharePointListServiceUri,
                                                                        _settings.SharePointListID, new CoursesParser(),
                                                                        _settings.SharePointUpdateInterval);
            courseUpdater.Updated +=
                delegate(object sender, EventArgs<IEnumerable<Course>> e) { coursesItemsControl.ItemsSource = e.Result; };
            courseUpdater.Start();
        }

        private void InitializeBlogUpdater()
        {
            var blogUpdater = new WebClientFeedUpdater<IEnumerable<BlogPost>>(_settings.BlogsFeedUri,
                                                                              new BlogPostsParser(),
                                                                              _settings.BlogsFeedUpdateInterval);
            blogUpdater.Updated += delegate(object sender, EventArgs<IEnumerable<BlogPost>> e)
                                       {
                                           blogsItemsControl.ItemsSource = e.Result.Take(_settings.BlogsFeedItemLimit);
                                       };
            blogUpdater.Start();
        }

        private void InitializeWeatherUpdater()
        {
            var weatherUpdater = new WebClientFeedUpdater<Weather>(_settings.WeatherFeedUri, new WeatherParser(),
                                                                   _settings.WeatherFeedUpdateInterval);
            weatherUpdater.Updated += delegate(object sender, EventArgs<Weather> e) { weather.DataContext = e.Result; };
            weatherUpdater.Start();
        }

        private void InitializeTheme()
        {
            if (_settings.Theme == "Rotate")
            {
                Job job = new Job();
                DateTimeOffset noon = new DateTimeOffset(DateTime.Today.AddHours(12));
                job.Run.From(noon).Every.Days(1);
                _scheduler = new Scheduler();
                _scheduler.SubmitJob(job, (j) => Dispatcher.BeginInvoke(() => RotateTheme()));
            }
            else
            {
                Uri themeUri = new Uri(String.Format("/Themes/{0}.xaml", _settings.Theme), UriKind.Relative);
                UpdateThemeFromXaml(themeUri);
            }
        }

        private void RotateTheme()
        {
            string oldTheme = this.Theme;
            List<string> themes = new List<string>() { "BlueContrast", "BrightBlue", "DarkBlue", "WhiteBlue", "WhiteContrast", "WhiteGray" };
            themes.Remove(oldTheme);
            string newTheme = themes[new Random().Next(themes.Count)];
            this.Theme = newTheme;
            Uri themeUri = new Uri(String.Format("/Themes/{0}.xaml", newTheme), UriKind.Relative);
            UpdateThemeFromXaml(themeUri);
            Logger.WriteLine("Changed theme from {0} to {1}", oldTheme, newTheme);
        }

        private void UpdateThemeFromXaml(Uri xamlUri)
        {
            var dict = new ResourceDictionary
            {
                Source = xamlUri
            };

            foreach (var key in dict.Keys)
            {
                if (Resources[key] is SolidColorBrush && dict[key] is SolidColorBrush)
                {
                    var oldValue = Resources[key] as SolidColorBrush;
                    var newValue = dict[key] as SolidColorBrush;
                    oldValue.Color = newValue.Color;
                }
            }
        }

        private void TrainerImage_Loaded(object sender, EventArgs e)
        {
            var img = sender as Image;
            var bitmap = img.Source as BitmapSource;
            if (img.ActualHeight == default(double))
                return;

            var rg = new RectangleGeometry
                         {
                             RadiusX = 10,
                             RadiusY = 10,
                             Rect = new Rect
                                        {
                                            X = 2.5,
                                            Y = 0,
                                            Width = img.ActualWidth - 5,
                                            Height = img.ActualHeight
                                        }
                         };
            img.Clip = rg;
        }
    }
}